import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from queue import Queue
import time
import threading
import sys

from voice_with_talk import TalkResponsor
from voice_with_talk import VoiceProducer
from voice_with_talk import async_talk
from voice_with_talk import async_exit
from voice_with_talk import async_listener

'''
** 桌面布局 **
                            -----------------     ----------------
                            | 语言选择下拉框 |     | 对话任务选择框 |
                            -----------------     ----------------

                       |——————————————————————————————————————————|
                       |                                          |
                       |                                          |
                       |                                          |
-------------------    |                                          |   ------------------- 
|                  |   |                                          |   |                  |
|                  |   |                                          |   |                  |
|   对话人物头像    |   |                   会话框                  |   |     当前人物头像  |
|                  |   |                                          |   |                  |
|                  |   |                                          |   |                  |
-------------------    |                                          |   -------------------
                       |                                          |
                       |                                          |
                       |                                          |
                       |                                          |
                       |——————————————————————————————————————————|
                            -----------     -----------
                            | 开始按钮 |     | 结束按钮 |
                            -----------     -----------
'''

class DialogueApp:
    def __init__(self, master: tk.Tk):
        self._user_queue = Queue()
        self._voicer_queue = Queue()
        self.lang_option = ['zh', 'en']
        self.people_option = [
            'longyingjing',
            'longyingtao',
            'longanrou',
            'longqiang_v2',
            'longhan_v2',
            'longcheng_v2',
            'longxiaocheng_v2',
            'longtian_v2',
            'longshao_v2',
            ]
        self.master = master
        master.title("对话窗口")
        container = tk.Frame(master)
        container.grid(row=0, column=0, sticky='nsew')
        master.grid_rowconfigure(0, weight=1)  # 仅中间部分随窗口扩展
        master.grid_columnconfigure(0, weight=1)

        frame_combo = tk.Frame(container)
        frame_combo.grid(row=0, column=0, sticky='nsew')
        frame_text = tk.Frame(container)
        frame_text.grid(row=1, column=0, sticky='nsew')
        frame_button = tk.Frame(container)
        frame_button.grid(row=2, column=0, sticky='nsew')

        self.lang_combo_box = ttk.Combobox(frame_combo, values=self.lang_option, state='readonly')
        self.lang_combo_box.current(0)
        self.lang_combo_box.bind("<<ComboboxSelected>>", self.language_change)
        self.lang_combo_box.pack(side=tk.LEFT, padx=10, fill=tk.Y)

        TalkResponsor.language = self.lang_combo_box.get()

        self.voicer_combo_box = ttk.Combobox(frame_combo, values=self.people_option, state='readonly')
        self.voicer_combo_box.current(0)
        self.voicer_combo_box.bind("<<ComboboxSelected>>", self.people_change)
        self.voicer_combo_box.pack(side=tk.RIGHT, ipadx=20, fill=tk.Y)

        self.voicer = self.voicer_combo_box.get()
        VoiceProducer.voice_author = self.voicer
        
        # 创建文本框用于显示对话内容
        center_frame = tk.Frame(frame_text)
        center_frame.grid(row=0, column=1)
        scrollbar = tk.Scrollbar(center_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.text_box = tk.Text(center_frame, wrap=tk.WORD, yscrollcommand=scrollbar.set, spacing2=5)
        self.text_box.pack()
        self.text_box.tag_configure("left", background="#C2EFF9", foreground="black", 
                        spacing2=15, lmargin1=10, lmargin2=10, rmargin=80,
                        justify='left', relief='groove', borderwidth=2)

        self.text_box.tag_configure("right", background="#F0A6D9", foreground="black",
                        spacing2=15, lmargin1=80, lmargin2=10, rmargin=10,
                        justify='right', relief='groove', borderwidth=2)
        self.text_box.config(state=tk.DISABLED)
        
        right_frame = tk.Frame(frame_text)
        right_frame.grid(row=0, column=2)
        image = Image.open('./image/right.jpg')
        image = image.resize((300, int(300*image.size[1]/image.size[0])), Image.Resampling.LANCZOS)
        self.photo = ImageTk.PhotoImage(image)
        self.right_image_label = tk.Label(right_frame, image=self.photo)
        self.right_image_label.pack(pady=20)

        
        left_frame = tk.Frame(frame_text)
        left_frame.grid(row=0, column=0)
        image = Image.open('./image/' + self.voicer + '.png')
        image = image.resize((300, int(300*image.size[1]/image.size[0])), Image.Resampling.LANCZOS)
        self.left_photo = ImageTk.PhotoImage(image)
        self.left_image_label = tk.Label(left_frame, image=self.left_photo)
        self.left_image_label.pack(pady=20)
        
        
        self.start_talk_button = tk.Button(frame_button, text="开始", command=self.start_talk)
        self.start_talk_button.pack(side=tk.LEFT, padx=10, fill=tk.Y)
        self.end_talk_button = tk.Button(frame_button, text="停止", command=self.end_talk)
        self.end_talk_button.pack(side=tk.RIGHT, ipadx=20, fill=tk.Y)
        self.end_talk_button.config(state=tk.DISABLED)

        self._working_update = True
        self._update_worker = threading.Thread(target=self.__update_text)
        self._update_worker.start()

    def exit(self):
        self._working_update = False
        if self._update_worker is not None and self._update_worker.is_alive():
            self._update_worker.join()


    def language_change(self, event):
        TalkResponsor.language = self.lang_combo_box.get()
        if 'en' == self.lang_combo_box.get():
            self.master.title("Talk Window")
            self.start_talk_button.config(text="Start Talk")
            self.end_talk_button.config(text="End Talk")
        else:
            self.master.title("对话窗口")
            self.start_talk_button.config(text="开始")
            self.end_talk_button.config(text="停止")

    def people_change(self, event):
        self.voicer = self.voicer_combo_box.get()
        VoiceProducer.voice_author = self.voicer
        image = Image.open('./image/' + self.voicer + '.png')
        image = image.resize((300, int(300*image.size[1]/image.size[0])), Image.Resampling.LANCZOS)
        self.left_photo = ImageTk.PhotoImage(image)
        self.left_image_label.config(image=self.left_photo)
        
    def start_talk(self):
        print("start_talk")
        self.start_talk_button.config(state=tk.DISABLED)
        self.end_talk_button.config(state=tk.NORMAL)
        self.lang_combo_box.config(state='disable')
        self.voicer_combo_box.config(state='disable')
        async_talk()

    def end_talk(self):
        print("end talk")
        self.end_talk_button.config(state=tk.DISABLED)
        self.start_talk_button.config(state=tk.NORMAL)
        self.lang_combo_box.config(state='readonly')
        self.voicer_combo_box.config(state='readonly')
        async_exit()


    def push_text(self, role: str, text: str):
        if role == 'user':
            self._user_queue.put(text)
        else:
            self._voicer_queue.put(text)
    
    def __update_text(self):
        while self._working_update:
            if not self._user_queue.empty():
                if self.text_box.cget('state') == tk.DISABLED:
                    self.text_box.config(state=tk.NORMAL)

                    # 插入内容并应用 tag
                    self.text_box.insert(tk.END, self._user_queue.get() + "\n", "right")
                    self.text_box.see(tk.END)  # 自动滚动到底部
                    self.text_box.config(state=tk.DISABLED)

            if not self._voicer_queue.empty():
                if self.text_box.cget('state') == tk.DISABLED:
                    self.text_box.config(state=tk.NORMAL)

                    # 插入内容并应用 tag
                    self.text_box.insert(tk.END, self._voicer_queue.get() + "\n", "left")
                    self.text_box.see(tk.END)  # 自动滚动到底部
                    self.text_box.config(state=tk.DISABLED)

            if self._user_queue.empty and self._voicer_queue.empty():
                time.sleep(0.1)

if __name__ == '__main__':
    root = tk.Tk()
    app = DialogueApp(root)
    async_listener(app.push_text)
    def exit_handle():
        app.exit()
        root.destroy()
        sys.exit()
    root.protocol("WM_DELETE_WINDOW", exit_handle)
    root.resizable(False, False)
    root.mainloop()